package com.mew.slots.core.common.roller.ili.xml;


import com.mew.common.util.RollerDownUtils;
import com.mew.common.util.StringUtils;
import com.mew.slots.core.common.roller.ili.InRoom;
import com.mew.slots.core.common.roller.ili.a.Ili;
import com.mew.slots.core.common.roller.ili.a.Iliread;
import com.mew.slots.core.common.roller.ili.b.IliB;
import com.mew.slots.core.common.roller.ili.b.IliBread;
import lombok.Data;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.*;

@Data
@ToString
@Component
@Slf4j
public abstract class IliXml {

    public int row;
    public int col;
    /**
     * 0  第一版
     * 1 第一版带名字
     * 2 第二版
     */
    public int ilitype;
    //根路径
    public static String rootpath = System.getProperty("user.dir");
    //路径
    public ArrayList<String> paths = new ArrayList<>();
    //库路径
    public String ilipath;

    //结果
    //库
    public Ili ili;
    public IliB iliB;
    //轴  控制库图标的几率
    private HashMap<Integer, HashMap<Integer,IliRoller>> rollers = new HashMap<>();


    public HashMap<Integer,IliRoller> initXmlIli(File file) throws Exception {

        SAXReader reader = new SAXReader();
        Document document = reader.read(file);

        String xpath = "/Root/CtrlConfig";///Item[@ID='1']
        Element node = (Element)document.selectSingleNode(xpath);

        HashMap<Integer,IliRoller> iliRollers = new HashMap<>();
        //遍历子节点

        for(Iterator it = node.elementIterator(); it.hasNext();){

            //节点
            Element next = (Element) it.next();
            List attributes = next.attributes();
            IliRoller roller = new IliRoller();
            for (int i = 0; i < attributes.size(); i++) {
                Attribute a = (Attribute) attributes.get(i);
                String name = a.getName();
                String value = a.getValue();
                if ("ID".equals(name)){
                    roller.setId(Integer.parseInt(value));
                }else if ("max".equals(name)){
                    roller.setMax(Integer.parseInt(value));
                }else if ("min".equals(name)){
                    roller.setMin(Integer.parseInt(value));
                }else if ("Name".equals(name)){
                    roller.setName(value);
                }else {
                    roller.getOthers().put(name,Integer.parseInt(value));
                }

                //权重
                int w = 0;
                for(Iterator n = next.elementIterator();n.hasNext();){

                    ArrayList clist = new ArrayList(){
                        {
                            add(null);
                            add(null);
                        }
                    };
                    //节点
                    Element cl = (Element) n.next();
                    List clattributes = cl.attributes();
                    for (int j = 0; j < clattributes.size(); j++) {
                        Attribute ca = (Attribute) clattributes.get(j);
                        String cname = ca.getName();
                        String cvalue = ca.getValue();

                        if ("Name".equals(cname)){
                            clist.set(1,cvalue);
                        }else if ("Scaled".equals(cname)){
                            w += Integer.parseInt(cvalue);
                            clist.set(0,w);
                        }
                    }

                    roller.roller.add(clist);
                }
                //总权重
                roller.all = w;
            }
            //存到什么地方
            iliRollers.put(roller.id,roller);
        }

        boolean err = false;
        HashSet name = new HashSet();
        for (IliRoller roller : iliRollers.values()) {
            for (ArrayList list : roller.roller) {
                if (ilitype==0||ilitype==1){
                    if (!ili.iarrays.keySet().contains(list.get(1))){
                        name.add(list.get(1));
                        err = true;
                    }

                }else {
                    if (!iliB.iarrays.keySet().contains(list.get(1))){
                        name.add(list.get(1));
                        err = true;
                    }
                }
            }
        }

        if (err){
            StringBuilder builder = new StringBuilder("不存在： ");
            name.forEach(n->builder.append(n+" "));
            log.info("轴库不对应 "+builder.toString());
            throw new Exception("轴库不对应 "+builder.toString());
        }
        file.delete();
        return iliRollers;
    }

    private void initIli() throws Exception{
        File file =  new File(rootpath+ File.separator + ilipath);
        // 存在就读  读完就删除
        if(file.exists()){
            if (this.ilitype == 0){
                ili = new Iliread().read(file,col*row);
            }else if (this.ilitype == 1){
                ili = new Iliread().read2(ilipath,col*row);
            }else if (this.ilitype == 2){
                iliB = new IliBread().read(file,col*row);
            }else {
                ili = new Iliread().read(file,col*row);
                if (null==ili){
                    iliB = new IliBread().read(file,col*row);
                }
            }
            file.delete();
            initSpe();
        }
    }

    /**
     * 特殊
     * @throws Exception
     */
    public void initSpe() throws Exception{

    };

    public IliRoller getIliRoller(Integer idx, Integer roller)  {

        return rollers.get(idx).get(roller);

    };

    private Random random = new Random();

    /**
     * type -1 特殊免费, 0 都出, 1 只取倍数
     * @param path
     * @param rollerId
     * @param in
     * @param type
     * @return
     */
    public ArrayList<Integer> getLine(int path, int rollerId , InRoom in, int type) {

        ArrayList<Integer> integers = null;

        StringBuilder builder = new StringBuilder();


        builder.append("type："+type+"  xml："+path+"  ");


        if (null!=in && in.getNum()<in.getItemNum()){
            //in.getNum()由1开始

            int i = in.getNum() + 1;
            builder.append("  name: "+in.getName()+" itemNum:"+in.getItemNum()+" "+" num:"+(i));
            IliB.Iarray iarray = iliB.iarrays.get(in.getName());

            IliB.Item item = iarray.getIt().get(in.getIarrNum());
            integers = (ArrayList<Integer>) item.getIc().get(in.getNum()).clone();
            in.setNum(i);

            if (i==in.getItemNum()){
                builder.append(" over");
            }
        }else {
            //轴
            IliRoller iliRoller = this.getIliRoller(path, rollerId);
            int rand = 0;
            String name = "";

            boolean run = false;
            //只出倍数范围
            do {
                rand = random.nextInt(iliRoller.getAll());

                name = getName(iliRoller, rand);

                if (name.indexOf("-")==-1 && type == 1){
                    run = true;
                }else if (name.indexOf("-")!=-1 && type == -1){
                    run = true;
                }else {
                    run = false;
                }

            }while (run);

            builder.append("  name："+name);
            if (StringUtils.isEmpty(name)){

                log.info(builder.toString()+"  null");
                return null;
            }

            if (null!=ili){
                builder.append("  A");
                Ili.Iarray iarray = ili.iarrays.get(name);
                if (null==iarray||iarray.getIc().isEmpty()){
                    builder.append("  no roller");
                    log.info(builder.toString());
                    return null;
                }
                int anInt = random.nextInt(iarray.getIc().size());
                builder.append("  num:"+anInt+" ");

                integers = (ArrayList<Integer>) iarray.getIc().get(anInt).clone();
            }else {
                builder.append("  B");
                IliB.Iarray iarray = iliB.iarrays.get(name);
                if (null==iarray||iarray.getIt().isEmpty()){
                    builder.append("  no roller");
                    log.info(builder.toString());
                    return null;
                }

                int anInt = random.nextInt(iarray.inum);
                builder.append("  inum:"+anInt+" ");

                IliB.Item item = iarray.getIt().get(anInt);
                integers = (ArrayList<Integer>) item.getIc().get(0).clone();

                in.setName(name);
                in.setIarrNum(anInt);
                in.setItemNum(item.inum);
                in.setNum(1);

            }

            //c转java
            this.ctoj(integers);


        }

        log.info(builder.toString()+"  "+integers.toString());

        return integers;
    }

    public int[] getLineints(int path, int rollerId ,InRoom in,int type) {
        ArrayList<Integer> line = this.getLine(path, rollerId, in, type);

        return line.stream().mapToInt(Integer::intValue).toArray();
    }

    /**
     * 第一种库
     * @param path
     * @param rollerId
     * @return
     */
    public int[] getLineints(int path, int rollerId ) {
        ArrayList<Integer> line = this.getLine(path, rollerId, null, path);
        return line.stream().mapToInt(Integer::intValue).toArray();
    }

    /**
     * 第一种库
     * @param path
     * @param rollerId
     * @return
     */
    public ArrayList<Integer> getLine(int path, int rollerId ){
        ArrayList<Integer> line = this.getLine(path, rollerId, null, path);
        return line;
    }


    /**
     * 拿特殊
     * 有连续继续走特殊
     * @return
     */
    public ArrayList<Integer> getSpe(String name,InRoom in){

        ArrayList<Integer> integers = null;

        StringBuilder builder = new StringBuilder();

        builder.append("特殊控制："+name);

        if (null!=in && in.getNum()<in.getItemNum()){
            //in.getNum()由1开始

            int i = in.getNum() + 1;
            builder.append("  连续图 "+in.getName()+"倍"+"共"+in.getItemNum()+"张 "+"第"+(i)+"张");
            IliB.Iarray iarray = iliB.iarrays.get(in.getName());

            IliB.Item item = iarray.getIt().get(in.getIarrNum());
            integers = (ArrayList<Integer>) item.getIc().get(in.getNum()).clone();
            in.setNum(i);

            if (i==in.getItemNum()){
                builder.append("------连续图案完毕------");
            }
        }else {

            if (null!=ili){
                builder.append("  A库");
                Ili.Iarray iarray = ili.iarrays.get(name);
                if (null==iarray||iarray.getIc().isEmpty()){
                    builder.append("  轴库不对应");
                    log.info(builder.toString());

                    return null ;
                }
                int anInt = random.nextInt(iarray.getIc().size());
                builder.append("  第"+anInt+"张图");

                integers = (ArrayList<Integer>) iarray.getIc().get(anInt).clone();
            }else {
                builder.append("  B库");
                IliB.Iarray iarray = iliB.iarrays.get(name);
                if (null==iarray||iarray.getIt().isEmpty()){
                    builder.append("  轴库不对应");
                    log.info(builder.toString());

                    return null ;
                }

                int anInt = random.nextInt(iarray.inum);
                builder.append("  第"+anInt+"项");

                IliB.Item item = iarray.getIt().get(anInt);
                integers = (ArrayList<Integer>) item.getIc().get(0).clone();

                in.setName(name);
                in.setIarrNum(anInt);
                in.setItemNum(item.inum);
                in.setNum(1);

                builder.append("  "+item.toString());
            }


            //c转java
            this.ctoj(integers);

        }

        log.info(builder.toString()+"  "+integers.toString());

        return integers;
    }

    /**
     * 拿特殊
     * 有连续继续走特殊
     * @return
     */
    public ArrayList<Integer> getSpe(String name){

        return this.getSpe(name,null );
    }

    public int[] getSpeints(String name,InRoom in){
        ArrayList<Integer> spe = this.getSpe(name, in);

        int[] ints = new int[spe.size()];

        for (int i = 0; i < spe.size(); i++) {
            ints[i] = spe.get(i);
        }

        return ints;
    }

    public int[] getSpeints(String name){
        return this.getSpeints(name,null );
    }

    private String getName(IliRoller iliRoller, int rand) {
        //概率取出奖倍数
        String name = "";
        for (int i = 0; i < iliRoller.roller.size(); i++) {
            ArrayList<ArrayList> r = iliRoller.roller;
            ArrayList list = r.get(i);
            int o = (int) list.get(0);
            if (rand<o){
                name = (String) list.get(1);

                break;
            }
        }
        return name;
    };

    //c转java
    public void ctoj(ArrayList<Integer> line){

    };

    public abstract void initPathsRowColIlitype();

    public void init() throws Exception{
        // 轴 库 读取分离
        //初次读
        if(null==rollers||rollers.isEmpty()||(null == ili && null ==iliB)){
            initPathsRowColIlitype();
            downXml();
        }
        initIli();
        xml2rollers();
    }
    private void xml2rollers() throws Exception {
        for (int i = 0; i < paths.size(); i++) {
            File file = new File(rootpath + File.separator + paths.get(i));
            if(file.exists()){
                HashMap<Integer,IliRoller> iliRollers = initXmlIli(file);
                this.rollers.put(i,iliRollers);
            }

        }
    }

    ;

    public void downXml() throws Exception{

        if (StringUtils.isNotEmpty(ilipath)){

            int li = ilipath.lastIndexOf("/");

            String div = ilipath.substring(0, li);

            File divfile = new File(rootpath +"/"+ div);
            //文件夹是否存在
            if ( !divfile.exists()){
                divfile.mkdir();
            }

            //库不存在  下载库
            if ( !new File(rootpath +File.separator+ ilipath).exists()){
                RollerDownUtils.downIli(ilipath);
            }
            //轴不存在 下载轴
            for (String path : paths) {
                File file = new File(rootpath +File.separator+path);
                if (StringUtils.isNotEmpty(path) && !file.exists()){
                    //下载轴
                    RollerDownUtils.downXml(path);
                }
            }
        }

    }

    public void errXml() throws Exception{

        if (StringUtils.isNotEmpty(ilipath)){

            int li = ilipath.lastIndexOf("/");

            String div = ilipath.substring(0, li);

            File divfile = new File(rootpath  +"/"+ div);
            //文件夹是否存在
            if ( !divfile.exists()){
                divfile.mkdir();
            }

            //下载库
            RollerDownUtils.downIli(ilipath);

            //下载轴
            for (String path : paths) {
                File file = new File(path);
                //下载轴
                RollerDownUtils.downXml(path);

            }
        }
    }
}

